package com.ai.nsa.security;

import com.ai.nsa.NSAException;
import com.asiainfo.appserver.utils.StringUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.security.User;
import org.apache.hadoop.hbase.zookeeper.ZKUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.util.Properties;

/**
 * 华为大数据平台鉴权类
 *
 * @author Feng Chen 2017/6/21.
 */
public abstract class HwKerberos {

    private static String keytabfile;
    private static String principal;
    private static String jaas;
    private static String krb5;
    private static String confDir;

    public static boolean isAuth = false; // true执行鉴权，false不执行鉴权

    private final static Logger logger = LoggerFactory.getLogger(HwKerberos.class);

    static {
        configure();
    }


    /**
     * 鉴权
     */
    public static void auth(Configuration conf) {

        if (!isAuth) {
            logger.info("##########----------不执行华为大数据平台鉴权----------##########");
            return;
        }

        if (User.isHBaseSecurityEnabled(conf)) {
            logger.info("------华为大数据平台鉴权开始------");
            logger.info("华为大数据平台鉴权文件路径: {}", confDir);

            // jaas.conf file, it is included in the client pakcage file
            System.setProperty("java.security.auth.login.config", confDir + jaas);

            // set the kerberos server info,point to the kerberosclient
            System.setProperty("java.security.krb5.conf", confDir + krb5);

            // set the keytab file name
            conf.set("username.client.keytab.file", confDir + keytabfile);

            // set the user's principal
            conf.set("username.client.kerberos.principal", principal);

            try {
                long start = System.currentTimeMillis();
                User.login(
                        conf,
                        "username.client.keytab.file",
                        "username.client.kerberos.principal",
                        InetAddress.getLocalHost().getCanonicalHostName()
                );

                long end = System.currentTimeMillis();
                logger.info("User.login耗时:" + (end - start) + "ms");

                ZKUtil.loginClient(conf, "username.client.keytab.file",
                        "username.client.kerberos.principal", InetAddress
                                .getLocalHost().getCanonicalHostName());
                logger.info("ZKUtil.loginClient耗时:"
                        + (System.currentTimeMillis() - end) + "ms");

                logger.info("------华为大数据平台鉴权结束------");

            } catch (IOException e) {
                logger.error("", e);
                throw new NSAException("HwKerberos Auth failed.", e);
            }
        } else {
            logger.error("------未加载华为大数据平台鉴权------");
        }

    }


    // SECTION: INNER HELPER

    private static void configure() {
        InputStream inputStream = null;
        Properties props = new Properties();
        try {
            inputStream = HwKerberos.class.getClassLoader().getResourceAsStream("kerberos.properties");
            props.load(inputStream);
        } catch (IOException e) {
            logger.error("", e);
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    // nothing to do
                }
            }
        }

        keytabfile = props.getProperty("keytabfile");
        principal = props.getProperty("principal");
        jaas = props.getProperty("jaas");
        krb5 = props.getProperty("krb5");

        isAuth = StringUtils.equalsIgnoreCase("true", props.getProperty("isauth"));
        confDir = HwKerberos.class.getClassLoader().getResource("").getFile();
    }

}
